'''
抢占式多任务和协同多任务
抢占式多任务是操作系统决定 多线程或多进程
协同多任务 在应用程序中显式地编写代码让其他任务先去运行
GIL锁 一个Python进程 一次同时只能有一个线程运行Python代码 GIL的存在是因为Python管理内存是引用计数方式实现不是线程安全的
当IO操作发生时，全局解释器锁被释放。这让我们可以在涉及IO时 使用多个线程来执行并发工作，但不用于CPU密集型工作释放。
asyncio并没有绕过GIL 如果有CPU密集型任务 仍然需要多个进程 由于有GIL的存在能做的就是并行化IO操作 在给定的事件只有一段Python代码在执行
每个任务等待IO的重叠时asyncio真正节省时间的地方 asyncio主要帮助我们使IO密集型工作并发执行
线程通常只能用于Python中有效管理IO密集型工作因为GIL会组织代码并行执行
事件循环是asyncio应用程序的核心 事件循环会一直循环下去寻找CPU密集型任务同时暂停正在等待IO的任务
多个线程同时运行每个线程都有自己的并发IO 类似的 也可以多个协程同时运行在等待IO密集型协程完成时仍可以执行其他Python代码
'''

import threading

def hello():
    # Thread适用IO型操作 因为IO这样的低级调用在Python运行时之外 这时允许GIL被释放 因为它不直接与Python对象交互 这种情况下GIL只有接收到数据被转换回Python对象GIL锁才会被重新获取
    print(f"hello {threading.current_thread()}") 

hello_thread1 = threading.Thread(target=hello)
hello_thread1.start()
hello_thread2 = threading.Thread(target=hello)
hello_thread2.start()

hello_thread1.join()
hello_thread2.join()